#define MSPROTOCOL_C
#include <stdlib.h> 
#include <stdio.h>
#include <string.h> 
#include <unistd.h>
#include <libmscommon/mscommon.h>
#include <libmscommon/msstring.h>
#include <libmscommon/mstime.h>
#include <libmslog/mslog.h>
#include "msprotocol.h" 

#define FLAG "msprotocol"

static URLProtocol 		*first_protocol 	= ms_null;

#define enable_rtp_debug	ms_false

static int ffurl_register_protocols(URLProtocol *protocol, int size)
{
	 URLProtocol **p;
    	if (size < sizeof(URLProtocol)) {
       	 	URLProtocol* temp = ms_malloc(sizeof(URLProtocol),"URLProtocol");
       	 	memcpy(temp, protocol, size);
        	protocol = temp;
    	}
	p = &first_protocol;
    	while (*p != ms_null){
		p = &(*p)->next;
	}
	*p = protocol;
    	protocol->next = ms_null;
    	return 0;
}
void * msprotocol_api_match(const char *name)
{
	URLProtocol **p= &first_protocol;
	
	if(ms_null==name){
		return ms_null ;
	}
	
	while (*p != ms_null){
		if( ms_strncmps_aeq(name, (*p)->name)){
			break;
		}
		p = &(*p)->next;
	}
	return (void *)*p ;
}
URLProtocol * msprotocol_api_matchurl(const ms_u08 *url)
{
	URLInfo url_info;//set by call msstr_api_urlsplit	
	ms_u08 tbuf[mscfg_maxlen_url]={0};
	ms_strcpy(tbuf, url);
	msstr_api_urlsplit_autosize(url_info.protocol_name, 
		url_info.authorization, 
		url_info.hostname, 
		&url_info.port, 
		url_info.path, 
		&url_info.flag_ipv6,
		tbuf);
	
	URLProtocol * purl_ptl= (URLProtocol * )msprotocol_api_match(url_info.protocol_name);//Get the right protocol
	if(ms_null==purl_ptl){
		purl_ptl=msprotocol_api_match(PTLNAME_MSAV);ms_debug( "in-use:%s",purl_ptl->name);
	}
	if(ms_null==purl_ptl){
		ms_errret(ms_null, "Unfind  protocol out");
	}
	return purl_ptl;
}
URLProtocol * msprotocol_api_matchurl2(const ms_u08 *url,URLInfo *purl_info)
{
	ms_u08 tbuf[mscfg_maxlen_url]={0};
	ms_strcpy(tbuf, url);
	msstr_api_urlsplit_autosize(purl_info->protocol_name,
		purl_info->authorization, 
		purl_info->hostname, 
		&purl_info->port, 
		purl_info->path, 
		&purl_info->flag_ipv6,
		tbuf);
	URLProtocol * purl_ptl= (URLProtocol * )msprotocol_api_match(purl_info->protocol_name);//Get the right protocol
	if(ms_null==purl_ptl){
		purl_ptl=msprotocol_api_match(PTLNAME_MSAV);ms_debug( "in-use:%s",purl_ptl->name);
	}
	return purl_ptl;
}


ENUPROTOCOLIndex msprotocol_api_getprotocol(char *url,char *format,ms_bool isvod)
{
	bufcheck_ret(msptc_unknow, url);
	if(ms_strncmps_eq(url,"file")){
		return msptc_file;
	}else if(ms_strncmps_eq(url,"udp")){
		return msptc_udp;
	}else if(ms_strncmps_eq(url,"rtp")){
		return msptc_rtp;
	}else if(ms_strncmps_eq(url,"rtmp")){
		return msptc_rtmp;
	}else if(ms_strncmps_eq(url,PTLNAME_MSOSHLS)){
		return msptc_msoshls;
	}else if((msstr_api_iscasestr(url, "m3u8") !=0)
		||ms_strncmps_eq(url,PTLNAME_HLS)
		||(ms_null!=format &&(ms_buflen(format)>0)&& ms_strncmps_aeq(format,"hls,applehttp"))){
		return msptc_hls;
	}else if(ms_strncmps_eq(url,"http")){
		 if(ms_false!=isvod){
		 	return msptc_http_vod;	
		 }else{
			return msptc_http;
		 }
	}else if(ms_strncmps_eq(url,"rtsp")){
		return msptc_rtsp;
	}else if(ms_strncmps_eq(url,"tcp")){
		return msptc_tcp;
	}else if(ms_strncmps_eq(url,"srt")){
		return msptc_srt;
	}else if(ms_strncmps_eq(url,"none")){
		return msptc_none;
	}else if(ms_strncmps_eq(url,"raw")){
		return msptc_raw;
	}else{
		return msptc_unknow;
	}
}
ms_void msprotocol_api_rtpiframe_debug(RTSPINTERLEAVEDFRAMEContext *prtspif_ctt,ms_bool enable_debug)
{
	ms_endbg(enable_debug, "========B rtp interleaver frame====================");
	ms_endbg(enable_debug, "-------magic:%#x",prtspif_ctt->magic);
	ms_endbg(enable_debug, "-------channel:%#x(0-rtp,1-rtcp)",prtspif_ctt->channel);
	ms_endbg(enable_debug, "-------len:%d",prtspif_ctt->len);
	ms_endbg(enable_debug, "========E rtp interleaver frame====================");
}
ms_s32 msprotocol_api_rtpiframe_set(ms_u08 *buf,ms_s32 len,ms_bool is_offset)
{
	if(ms_true==is_offset){
		ms_selfcp(buf, (-RTP_INTERLEAVERFRAME_LEN), len)
	}
	buf[0]=RTP_MAGIC_NUM;
	buf[1]=RTSP_DATATYPE_RTP;
	ms_network_2b(&buf[2], len);
	return (len+RTP_INTERLEAVERFRAME_LEN);
}

RTSPDATAType msprotocol_api_rtpiframe_get(RTSPINTERLEAVEDFRAMEContext *prtspif_ctt,ms_u08 *buf,ms_s32 len)
{
	ms_memset(prtspif_ctt, 0, sizeof(RTSPINTERLEAVEDFRAMEContext));
	ms_s32 index=0;
	for(index=0;index<len;index++){
		if(RTP_MAGIC_NUM==buf[index]){
			break;
		}
	}
	if(!(index<len)){
		//ms_errret(-1,"No find rtp magic,maybe no rtp pkt");
		return RTSP_DATATYPE_ERR_NOMAGICNUM;
	}
	prtspif_ctt->magic		=RTP_MAGIC_NUM;
	prtspif_ctt->channel	=buf[index+1];
	if((prtspif_ctt->channel!=RTSP_DATATYPE_RTP)
		&&(prtspif_ctt->channel!=RTSP_DATATYPE_RTCP)){
		ms_dbgret(RTSP_DATATYPE_ERR_CHANNLE,"unknow channel(%d),drop it",prtspif_ctt->channel);
	}
	prtspif_ctt->len		=ms_host_2b((&buf[index+2]));
	if(prtspif_ctt->len  >  5000){
		ms_dbgret(RTSP_DATATYPE_ERR_DATALEN,"Rtsp to len(%d),may be error",prtspif_ctt->len);
	}
	msprotocol_api_rtpiframe_debug( prtspif_ctt, enable_rtp_debug);
	return prtspif_ctt->channel;
}
RTSPDATAType msprotocol_api_isrtspcmd(ms_pbyte recvbuf,int len)
{
	#define CMD_RTSP(string)	((len>ms_buflen(string)&&ms_strncmps_eq(recvbuf, string)))
	if(CMD_RTSP("OPTIONS")){
		ms_debug("rtsp cmd:OPTIONS");
		return RTSP_DATATYPE_ERR_CMD;
	}else if(CMD_RTSP("DESCRIBE")){
		ms_debug("rtsp cmd:DESCRIBE");
		return RTSP_DATATYPE_ERR_CMD;
	}else if(CMD_RTSP("ANNOUNCE")){
		ms_debug("rtsp cmd:ANNOUNCE");
		return RTSP_DATATYPE_ERR_CMD;
	}else if(CMD_RTSP("SETUP")){
		ms_debug("rtsp cmd:SETUP");
		return RTSP_DATATYPE_ERR_CMD;
	}else if(CMD_RTSP("PLAY")){
		ms_debug("rtsp cmd:PLAY");
		return RTSP_DATATYPE_ERR_CMD;
	}else if(CMD_RTSP("RECORD")){
		ms_debug("rtsp cmd:RECORD");
		return RTSP_DATATYPE_ERR_CMD;
	}else if(CMD_RTSP("GET_PARAMETER")){
		ms_debug("rtsp cmd:GET_PARAMETER");
		return RTSP_DATATYPE_ERR_CMD;
	}else if(CMD_RTSP("TEARDOWN")){
		ms_debug("rtsp cmd:TEARDOWN");
		return RTSP_DATATYPE_ERR_CMD;
	}
	return RTSP_DATATYPE_ERR_OK;
}
ms_u32 msprotocol_api_contextlen(char *inbuf,ms_u32 len)
{
	ms_u32 index=0;
	ms_bool flag_find=ms_false;
	for(index=0;index<(len-4);index++){
		if((inbuf[index]==0x0D)&&(inbuf[index+1]==0x0A)&&(inbuf[index+2]==0x0D)&&(inbuf[index+3]==0x0A)){
			flag_find=ms_true;
			break;
		}
	}
	return (flag_find==ms_true) ? (index+4) :  len;
}
RTSPDATAType msprotocol_api_rtpiframe_drop(MSFIFOSIZEContext  *plist_stream_fifoctt,ms_pbyte recvbuf,int *plen)
{
	MSFIFOBLOCKContext * pmsfifo_ctt=plist_stream_fifoctt->pmsfifo_ctt;

	plist_stream_fifoctt->fifosize_left=msfifoblock_api_sizeleft(pmsfifo_ctt);;
	if( plist_stream_fifoctt->fifosize_left<(*plen)) {/* No Space left */
		msfifoblock_api_flowoverreset(pmsfifo_ctt);
		plist_stream_fifoctt->num_reset=msfifoblock_api_numreset(pmsfifo_ctt);
		ms_waring("pmsfifo_ctt_rtpovertcp(%s) flowover,reset(%d<%d)",pmsfifo_ctt->name,plist_stream_fifoctt->fifosize_left,(*plen));
	}

	RTSPDATAType cdm_ret=msprotocol_api_isrtspcmd( recvbuf,  (*plen));
	if(RTSP_DATATYPE_ERR_OK!=cdm_ret){	
		ms_u32 len=4;
		ms_bool flag_findcmdend=ms_false;
		while((*plen)>len){
			if((recvbuf[len-3]==0x0D)&&(recvbuf[len-2]==0x0A)&&(recvbuf[len-1]==0x0D)&&(recvbuf[len]==0x0A)){
				ms_debug("------find rtsp cmd end,cmd_len,total_len:%d,%d",(len+1),(*plen));
				flag_findcmdend=ms_true;
				break;
			}
			len+=1;
		}
		ms_s32 data_len=0;
		if(ms_true==flag_findcmdend&&((*plen)>len)){
			data_len=(*plen)-(len+1);
		}else{
			ms_waring("------rtsp cmd,but no find cmdend(\\r\\n\\r\\n))");
			data_len=(*plen);
			(*plen)=len=0;
		}
		if(data_len>0){
			msfifoblock_api_in(pmsfifo_ctt, &recvbuf[len], data_len, NULL);
		}
		ms_dbgret(cdm_ret,"------rtsp cmd");
	}

	if((*plen)>0){
		msfifoblock_api_in(pmsfifo_ctt, recvbuf, (*plen), NULL);
	}
	
	ms_u32 sizeused=msfifoblock_api_sizeused(pmsfifo_ctt);
	if(ms_f32==sizeused){
		(*plen)=0;
		ms_errret(RTSP_DATATYPE_ERR_FIFOLEN,"Oh,my god.Data_size   is   %d ",sizeused);
	}
	if(sizeused>2000){
		msfifoblock_api_out(pmsfifo_ctt, recvbuf, 4, NULL);
		RTSPDATAType cdm_ret=msprotocol_api_isrtspcmd( recvbuf,  (*plen));
		if(RTSP_DATATYPE_ERR_OK!=cdm_ret){
			ms_bool flag_findcmdend=ms_false;
			ms_u32 len=4;
			while(sizeused>0){
				msfifoblock_api_out(pmsfifo_ctt, &recvbuf[len], 1, NULL);
				sizeused=msfifoblock_api_sizeused(pmsfifo_ctt);
				if((recvbuf[len-3]==0x0D)&&(recvbuf[len-2]==0x0A)&&(recvbuf[len-1]==0x0D)&&(recvbuf[len]==0x0A)){
					ms_debug("------find rtsp cmd end,cmd_len,total_len:%d,%d",(len+1),(*plen));
					flag_findcmdend=ms_true;
					break;
				}
				len+=1;
			}
			if(ms_true==flag_findcmdend&&((*plen)>len)){
				(*plen)=(len+1);
			}else{
				ms_waring("------rtsp cmd,but no find cmdend(\\r\\n\\r\\n))");
				(*plen)=0;
			}
			ms_dbgret(cdm_ret,"Oh,rtsp cmd ");
		}else{
			RTSPINTERLEAVEDFRAMEContext rtspif_ctt;
			RTSPDATAType ret=msprotocol_api_rtpiframe_get(&rtspif_ctt,recvbuf,4);
			if(RTSP_DATATYPE_RTP==ret){
				msfifoblock_api_out(pmsfifo_ctt, recvbuf,rtspif_ctt.len, NULL);
				(*plen)=rtspif_ctt.len;
			}else if(RTSP_DATATYPE_RTCP==ret){
				msfifoblock_api_out(pmsfifo_ctt, recvbuf,rtspif_ctt.len, NULL);
				(*plen)=rtspif_ctt.len;
			}else{
				(*plen)=0;
				ms_errret(RTSP_DATATYPE_ERR_UNKNOW,"msprotocol_api_rtpiframe_get  is failed(error_no=%d,pmsfifo_name:%s)",ret,pmsfifo_ctt->name);
			}
		}
		return RTSP_DATATYPE_RTP;
	}else{
		(*plen)=0;
		//ms_dbgret(RTSP_DATATYPE_ERR_FIFOLEN_TOOSMALL,"sizeused(%d) is too small",sizeused);
		return RTSP_DATATYPE_ERR_FIFOLEN_TOOSMALL;
	}
}
ms_void msprotocol_api_rtpiframe_bufdebug(ms_u08 *buf,ms_s32 len,ms_bool enable_debug)
{
	RTSPINTERLEAVEDFRAMEContext rtspif_ctt;
	ms_memset(&rtspif_ctt, 0, sizeof(RTSPINTERLEAVEDFRAMEContext));

	if(!(msprotocol_api_rtpiframe_get(&rtspif_ctt,buf, len)<0)){
		msprotocol_api_rtpiframe_debug( &rtspif_ctt, enable_debug);
	}	
}
ms_void msprotocol_api_rtpheader_debug(RTPHEADERContext *prh_ctt,ms_bool enable_debug)
{
	ms_endbg(enable_debug, "========B rtp===========header_total_len:%d", prh_ctt->header_total_len);
	
	ms_endbg(enable_debug, "num of csrc:%d", prh_ctt->cc);
	ms_endbg(enable_debug, "header extension:%d", prh_ctt->x);
	ms_endbg(enable_debug, "padding:%d", prh_ctt->p);
	ms_endbg(enable_debug, "version:%d", prh_ctt->v);
	
	ms_endbg(enable_debug, "playload:%d", prh_ctt->pt);
	ms_endbg(enable_debug, "m:%d", prh_ctt->m);
	
	ms_endbg(enable_debug, "sequence number:%d", prh_ctt->sequence_num);
	ms_endbg(enable_debug, "timestamp:%u", prh_ctt->timestamp);
	ms_endbg(enable_debug, "ssrc:%u", prh_ctt->ssrc);
	if(prh_ctt->cc>0){
		if( (prh_ctt->cc)  >  sizeof(prh_ctt->csrc)	){
			ms_waring("The csrc arry is only (%ld),but the num of csrc data is%d ,please modify the sourcecode",sizeof(prh_ctt->csrc),prh_ctt->cc );
		}else{
			ms_u32 index=0;
			for(index=0;index<prh_ctt->cc;index++){
				ms_endbg(enable_debug, "csrc%d:%u", index,prh_ctt->csrc[index]);
			}
		}
	}
	ms_endbg(enable_debug, "========E rtp============================");
}
ms_void msprotocol_api_rtpheader_get(RTPHEADERContext *prh_ctt,ms_u08 *buf,ms_s32 len,ms_bool debug)
{
	#define RTP_HEASER_LEN	12
	ms_memset(prh_ctt, 0, sizeof(RTPHEADERContext));
	//BYTE[0]
	prh_ctt->cc	=(buf[0]&0x0f);		//0-15
	prh_ctt->x	=(buf[0]&0x10)>>4;
	prh_ctt->p	=(buf[0]&0x20)>>5;
	prh_ctt->v	=(buf[0]&0xc0)>>6;
	 if(2!=prh_ctt->v){
	 	return;
	 }
	if(1==prh_ctt->p
		&& ms_true==debug){
		ms_waring("The rtp has padding,but I donot complex it,maybe there is a bug" );
		ms_buf("rtpbuf", buf, 16);
	}
	//BYTE[1]
	prh_ctt->pt	=(buf[1]&0x7f);
	prh_ctt->m	=(buf[1]&0x80)>>7;

	prh_ctt->sequence_num	=ms_host_2b(&buf[2]);
	prh_ctt->timestamp	=(ms_host_4b(&buf[4])*1000/90);	//khz,ms  mpegts->90khz
	prh_ctt->ssrc			=ms_host_4b(&buf[8]);
	
	//CSRC:Mixer uses
	if(prh_ctt->cc>0){
		if( (prh_ctt->cc)  >  sizeof(prh_ctt->csrc)	
			&& ms_true==debug){
			ms_waring("The csrc arry is only (%ld),but the num of csrc data is%d ,please modify the sourcecode",sizeof(prh_ctt->csrc),prh_ctt->cc );
		}else{
			ms_u32 index=0;
			for(index=0;index<prh_ctt->cc;index++){
				prh_ctt->csrc[index]=ms_host_4b(&buf[RTP_HEASER_LEN+4*index]);
			}
		}
	}

	//HEADER EXTENSION
	if(1==prh_ctt->x){
		prh_ctt->profile_data					=ms_host_2b(&buf[12+prh_ctt->cc*4]);
		prh_ctt->len_header_extension			=ms_host_2b(&buf[14+prh_ctt->cc*4]);
		
		if(prh_ctt->x > ms_arrayelems(prh_ctt->header_extension)
			&& ms_true==debug){
			ms_waring("The header_extension arry is only (%ld),but the num of header_extension data is %d,please modify the sourcecode",sizeof(prh_ctt->header_extension),prh_ctt->x );
		}else{
			ms_u32 index=0;
			for(index=0;index<prh_ctt->x;index++){
				prh_ctt->header_extension[index]=ms_host_4b(&buf[RTP_HEASER_LEN+(prh_ctt->cc*4)+4+4*index]);
			}
		}

		prh_ctt->header_total_len=RTP_HEASER_LEN+(prh_ctt->cc*4)+4+(prh_ctt->len_header_extension*4);
	}else{
		prh_ctt->header_total_len=RTP_HEASER_LEN+(prh_ctt->cc*4);
	}
	if(RTP_PAYLOADTYPE_MPA==prh_ctt->pt){
		prh_ctt->header_total_len+=4;
	}
}
ms_s32 msprotocol_api_rtpenc(RTPHEADERContext ms_in *prh_ctt,ms_u08 payload,ms_s08 ms_out *buf ,ms_s32 ms_out size,ms_bool is_offset)
{
	prh_ctt->isrtp=ms_true;
	if(ms_true!=prh_ctt->init){
		prh_ctt->header_total_len=RTP_HEASER_LEN;
		//BYTE[0]
		prh_ctt->cc	=0;
		prh_ctt->x	=0;
		prh_ctt->p	=0;
		prh_ctt->v	=0x2;
		//BYTE[1]
		prh_ctt->pt	=payload;	//33-MP2T,14-MPA
		prh_ctt->m	=0;
		prh_ctt->sequence_num	=0;
		prh_ctt->timestamp_base	=(ms_u32)mstime_api_us()*90/1000;	//khz,ms  mpegts->90khz
		prh_ctt->ssrc		 		=(ms_u32)mstime_api_us();
		//CSRC
		//HEADER EXTENSION
		prh_ctt->header_total_len=RTP_HEASER_LEN;
		prh_ctt->init=ms_true;
	}else{
		prh_ctt->sequence_num	+=1;
		prh_ctt->timestamp=((ms_u32)mstime_api_us()*90/1000-prh_ctt->timestamp_base);	//khz,ms  mpegts->90khz
	}
	
	if(ms_true==is_offset){
		if(RTP_PAYLOADTYPE_MPA==prh_ctt->pt){
			ms_selfcp(buf, -(RTP_HEASER_LEN+4), size);
		}else{
			ms_selfcp(buf, -RTP_HEASER_LEN, size);
		}
	}
	//BYTE[0]
	buf[0]=(prh_ctt->v<<6)|(prh_ctt->p<<5)|(prh_ctt->x<<4)|(prh_ctt->cc);
	//BYTE[1]
	buf[1]=(prh_ctt->m<<7)|(prh_ctt->pt);
	//BYTE[2:3]
	ms_network_2b(&buf[2], prh_ctt->sequence_num);
	//BYTE[4:7]
	ms_network_4b(&buf[4], prh_ctt->timestamp);
	//BYTE[8:11]
	ms_network_4b(&buf[8], prh_ctt->ssrc);
	
	if(RTP_PAYLOADTYPE_MPA==prh_ctt->pt){
		ms_network_4b(&buf[12], 0x0);
	}
	
	return   (RTP_PAYLOADTYPE_MPA==prh_ctt->pt)  ?  (size+RTP_HEASER_LEN+4)  :   (size+RTP_HEASER_LEN);
}
ms_void msprotocol_api_rtpheader_bufdebug(RTPContext * prtp_ctt,ms_string desinfo,ms_u08 *buf,ms_s32 len,ms_bool enable_debug)
{
	RTPContext rtp_ctt;
	if(prtp_ctt==ms_null){
		ms_memset_stru(&rtp_ctt, RTPContext);
		prtp_ctt=&rtp_ctt;
	}
	
	RTPHEADERContext *prh_ctt=&prtp_ctt->rtpheader_ctt;
	msprotocol_api_rtpheader_get(prh_ctt,buf,len,ms_true);
	msprotocol_api_rtpheader_debug(prh_ctt,enable_debug);	
	if( (0!=prtp_ctt->sequence_num_pre)
		&&ms_noless(prtp_ctt->sequence_num_pre, prh_ctt->sequence_num)
		&&ms_lessthan((prtp_ctt->sequence_num_pre-prh_ctt->sequence_num),100) 	){
		ms_waring("[%s]--%u--%u,error sequence_num_pre(sequence_num_pre>sequence_num)", 
			desinfo,
			prtp_ctt->sequence_num_pre, 
			prh_ctt->sequence_num);
			return;
	}
	if( (0!=prtp_ctt->sequence_num_pre)
		&&ms_lessthan(prtp_ctt->sequence_num_pre, prh_ctt->sequence_num)
		&&ms_noless((prh_ctt->sequence_num-prtp_ctt->sequence_num_pre), 30000)){
		ms_waring("[%s]--%u--%u,error sequence_num_pre(sequence_num_pre<sequence_num too much)",
			desinfo,
			prtp_ctt->sequence_num_pre, 
			prh_ctt->sequence_num);
		return;
	}
	prtp_ctt->sequence_num_pre=prh_ctt->sequence_num;
	//ms_enbuf(enable_debug, "data", &buf[prh_ctt.header_total_len], (len-prh_ctt.header_total_len));
}
ms_bool msprotocol_api_rtpheader_checksequence(RTPContext * prtp_ctt,ms_string desinfo,ms_u08 *buf,ms_s32 len)
{
	ms_pamcheckret(ms_false, prtp_ctt, "prtp_ctt");
	RTPHEADERContext *prh_ctt=&prtp_ctt->rtpheader_ctt;
	msprotocol_api_rtpheader_get(prh_ctt,buf,len,ms_true);
	msprotocol_api_rtpheader_debug(prh_ctt,ms_true);	
	ms_debug("[%s]--%u--%u,sequence_num_pre(sequence_num_pre>sequence_num)", 
		desinfo,
		prtp_ctt->sequence_num_pre, 
		prh_ctt->sequence_num);
	if( (0!=prtp_ctt->sequence_num_pre)
		&&ms_noless(prtp_ctt->sequence_num_pre, prh_ctt->sequence_num)
		&&ms_lessthan((prtp_ctt->sequence_num_pre-prh_ctt->sequence_num),100) 	){
		ms_waring("[%s]--%u--%u,error sequence_num_pre(sequence_num_pre>sequence_num)", 
			desinfo,
			prtp_ctt->sequence_num_pre, 
			prh_ctt->sequence_num);
			msprotocol_api_rtpheader_debug(prh_ctt,ms_true);	
			return ms_false;
	}
	if( (0!=prtp_ctt->sequence_num_pre)
		&&ms_lessthan(prtp_ctt->sequence_num_pre, prh_ctt->sequence_num)
		&&ms_noless((prh_ctt->sequence_num-prtp_ctt->sequence_num_pre), 30000)){
		ms_waring("[%s]--%u--%u,error sequence_num_pre(sequence_num_pre<sequence_num too much)",
			desinfo,
			prtp_ctt->sequence_num_pre, 
			prh_ctt->sequence_num);
		msprotocol_api_rtpheader_debug(prh_ctt,ms_true);	
		return ms_false;
	}
	prtp_ctt->sequence_num_pre=prh_ctt->sequence_num;
	return ms_true;
}

ms_void msprotocol_api_rtpovertcpheader_bufdebug(ms_u08 *buf,ms_s32 len,ms_bool enable_debug)
{
	RTPOVERTCPHEADERContext rtpovertcp_header_ctt;
	ms_memset(&rtpovertcp_header_ctt, 0, sizeof(RTPOVERTCPHEADERContext));

	RTSPINTERLEAVEDFRAMEContext *prtspif_ctt=&rtpovertcp_header_ctt.rtspif_ctt;
	RTPHEADERContext *prh_ctt=&rtpovertcp_header_ctt.rh_ctt;


	if(!(msprotocol_api_rtpiframe_get(prtspif_ctt,buf, len)<0)){
		msprotocol_api_rtpheader_get(prh_ctt,&buf[4],(len-4),ms_true);
		rtpovertcp_header_ctt.payload_len=prtspif_ctt->len-prh_ctt->header_total_len;
		
		msprotocol_api_rtpiframe_debug( prtspif_ctt, enable_debug);
		msprotocol_api_rtpheader_debug(prh_ctt,enable_debug);	
		ms_endbg(enable_debug, "payload_len:%d\r\n", rtpovertcp_header_ctt.payload_len);
	}
}
ms_bool msprotocol_api_rtpcheck(RTPHEADERContext *prh_ctt,ms_u08 *buf, int len ,ms_bool flag_checkiframe)
{
	/*BEGAIN:new pkt*/
	RTPHEADERContext rtpheader_ctt;
	if(prh_ctt==ms_null){
		prh_ctt=&rtpheader_ctt;
	}

	ms_u08 *pdatabuf=buf;
	int len_data=len;
	RTSPINTERLEAVEDFRAMEContext rtspif_ctt;
	if(ms_true==flag_checkiframe){
		if(!(msprotocol_api_rtpiframe_get(&rtspif_ctt, pdatabuf,len_data)<0)){
			pdatabuf=&buf[RTP_INTERLEAVERFRAME_LEN];
			len_data=len-RTP_INTERLEAVERFRAME_LEN;
		}else{
			prh_ctt->isrtp=ms_false;
			return prh_ctt->isrtp;
		}
	}
	msprotocol_api_rtpheader_get(prh_ctt,pdatabuf,len_data,ms_true);
	if((2!=prh_ctt->v)
		||ms_morethan(prh_ctt->header_total_len, len_data)
		||ms_morethan(prh_ctt->header_total_len, 64)
		||ms_lessthan(prh_ctt->header_total_len, 12)
	){
	#if 0	
		ms_waring("rtp version isnot 2---(%d),"
			"May the pkt is not a rtppkt,because of the too long header_total_len:%d ,data len %d---(%d)",
			(2!=prh_ctt->v) ,
			prh_ctt->header_total_len,len,
			(prh_ctt->header_total_len>64)	);
	#endif	
		prh_ctt->isrtp=ms_false;
	}else{
		prh_ctt->isrtp=ms_true;
	}
	return prh_ctt->isrtp; 
}

static ms_bool msprotocol_innerapi_rtpcheck_mp2t_mpa(RTPHEADERContext *prh_ctt,ms_u08 *buf, int len )
{
	/*BEGAIN:new pkt*/
	RTPHEADERContext rtpheader_ctt;
	if(prh_ctt==ms_null){
		prh_ctt=&rtpheader_ctt;
	}
	msprotocol_api_rtpheader_get(prh_ctt,buf,len,ms_false);
	if((2!=prh_ctt->v)
		||ms_morethan(prh_ctt->header_total_len, len)
		||ms_morethan(prh_ctt->header_total_len, 64)
		||ms_lessthan(prh_ctt->header_total_len, 12)
	){
	#if 0	
		ms_waring("rtp version isnot 2---(%d),"
			"May the pkt is not a rtppkt,because of the too long header_total_len:%d ,data len %d---(%d)",
			(2!=prh_ctt->v) ,
			prh_ctt->header_total_len,len,
			(prh_ctt->header_total_len>64)	);
	#endif	
		prh_ctt->isrtp=ms_false;
	}else{
		if(RTP_PAYLOADTYPE_MP2T!=prh_ctt->pt
			&&RTP_PAYLOADTYPE_MPA!=prh_ctt->pt){
			prh_ctt->isrtp=ms_false;
		}else{
			prh_ctt->isrtp=ms_true;
		}
	}
	return prh_ctt->isrtp; 
}


ms_bool msprotocol_api_rtpcheck_mp2t_mpa(RTPHEADERContext *prh_ctt,ms_u08 *buf, int len ,
	ms_bool flag_mpa2rtp,ms_byte *pdatatype_times,ms_bool *pflag_reset,ms_string name_des)
{
	RTPHEADERContext rtpheader_ctt_dec;
	msprotocol_innerapi_rtpcheck_mp2t_mpa(&rtpheader_ctt_dec, buf, len);
	ms_bool isrtp=prh_ctt->isrtp;
	if((ms_true==prh_ctt->isrtp)
		&&(ms_true==flag_mpa2rtp)){
		isrtp=ms_false;
	}
	(*pflag_reset)=mst_innerapi_datatype(&isrtp, &rtpheader_ctt_dec.isrtp,pdatatype_times,name_des, (ms_true==rtpheader_ctt_dec.isrtp)  ?  "udp"    :  "rtp", (ms_true==rtpheader_ctt_dec.isrtp)  ?  "rtp"  :  "udp");
	ms_memcpy(prh_ctt, &rtpheader_ctt_dec, ms_bufsize(RTPHEADERContext));
}

ms_s32 msprotocol_api_rtpfifoout(RTPContext * prtp_ctt,ms_u08 **ppbuf, int *len )
{
	if(ms_null==prtp_ctt->prtppktfifo_ctt){
		return -1;
	}
	ms_bool flag_must=ms_false;
ms_tryagain:
	if((MAXNUM_FIFO_RTPPKT/2)<prtp_ctt->rtptfifo_ptknum){
		prtp_ctt->sequence_num_need+=1;
		flag_must=ms_true;
	}
	ms_s32 index=0;
	for(index=0;index<MAXNUM_FIFO_RTPPKT;index++){
		RTPPKTFIFOContext *prtppktfifo_ctt=&prtp_ctt->prtppktfifo_ctt[index];
		if(ms_true==prtppktfifo_ctt->flag_use &&prtp_ctt->sequence_num_need==prtppktfifo_ctt->sequence_num){
			(*len)=prtppktfifo_ctt->sequence_num;
			(*len)=prtppktfifo_ctt->data_len;
			ms_memcpy((*ppbuf),prtppktfifo_ctt->data,prtppktfifo_ctt->data_len);
			prtp_ctt->rtptfifo_ptknum-=1;
			ms_memsetbuf(prtppktfifo_ctt->data);
			prtppktfifo_ctt->flag_use=ms_false;
			//ms_debug("get %d sequence_num(%d) to fifo%d---rtptfifo_ptknum:%d",prtppktfifo_ctt->data_len, prtppktfifo_ctt->sequence_num,index,prtp_ctt->rtptfifo_ptknum);
			return index;
		}
	}
	if(ms_true==flag_must){
		goto ms_tryagain;
	}
	return -1;
}
ms_void msprotocol_api_rtpfifoin(RTPContext * prtp_ctt,ms_u08 *buf, int *len ,ms_u16 sequence_num)
{
	if(ms_null==prtp_ctt->prtppktfifo_ctt){
		return ;
	}
	ms_s32 index=0;
	for(index=0;index<MAXNUM_FIFO_RTPPKT;index++){
		RTPPKTFIFOContext *prtppktfifo_ctt=&prtp_ctt->prtppktfifo_ctt[index];
		if(ms_false==prtppktfifo_ctt->flag_use){
			prtppktfifo_ctt->sequence_num=sequence_num;
			prtppktfifo_ctt->data_len=(*len);
			ms_memcpy(prtppktfifo_ctt->data, buf,prtppktfifo_ctt->data_len);
			prtppktfifo_ctt->flag_use=ms_true;
			prtp_ctt->rtptfifo_ptknum+=1;
			//ms_debug("put %d sequence_num(%d) to fifo%d------rtptfifo_ptknum:%d",prtppktfifo_ctt->data_len, prtppktfifo_ctt->sequence_num,index,prtp_ctt->rtptfifo_ptknum);
			break;
		}
	}
}
void msprotocol_api_rtpdec(RTPContext * prtp_ctt,ms_u08 *buf, int *len ,ms_bool flag_checkiframe)
{	
	/*BEGAIN:new pkt*/
	RTPContext rtp_ctt;
	if(prtp_ctt==ms_null){
		prtp_ctt=&rtp_ctt;
	}
	RTPHEADERContext *prh_ctt=&prtp_ctt->rtpheader_ctt;
ms_recheck:	
	if(ms_true==msprotocol_api_rtpcheck(prh_ctt,buf, (*len ),flag_checkiframe)){
		//ms_debug("---------------------------------------------sequence_num:%u,len:%d",prh_ctt->sequence_num,(*len));
		if(ms_true==prtp_ctt->flag_sequencenum_check){
			if((0!=prtp_ctt->sequence_num_need)
				&&(prtp_ctt->sequence_num_need!=prh_ctt->sequence_num)
			){
				/*
					if(sequence_num_need  >  sequence_num)
						30					20			drop  old pkt
						65536				1			nodrop
					else if(sequence_num_need  <  sequence_num)
						30					50			nodrop
						1					65536		drop  old pkt
					else if sequence_num_need  ==  sequence_num)
						30					30			nodrop
					else
						rtp fifoin

				*/
				if( ms_morethan(prtp_ctt->sequence_num_need, prh_ctt->sequence_num)
					&&ms_lessthan((prtp_ctt->sequence_num_need-prh_ctt->sequence_num),100) 	){
					(*len)=0;
					ms_debug("drop %u--%u,error sequence_num(sequence_num_need>sequence_num && sequence_num_need<(sequence_num+100))",
						prtp_ctt->sequence_num_need, prh_ctt->sequence_num);
					return;
				}else if( ms_lessthan(prtp_ctt->sequence_num_need, prh_ctt->sequence_num)
					&&ms_noless((prh_ctt->sequence_num-prtp_ctt->sequence_num_need), 30000)){
					(*len)=0;
					ms_debug("drop %u--%u,error sequence_num(sequence_num_need<sequence_num && (sequence_num_need+30000)<sequence_num)",
						prtp_ctt->sequence_num_need, prh_ctt->sequence_num);
					return;
				}else if(prtp_ctt->sequence_num_need==prh_ctt->sequence_num) {

				}else{
					if(ms_null!=prtp_ctt->prtppktfifo_ctt){
						//rtp(over udp) fifo:to correct sequence num
						msprotocol_api_rtpfifoin(prtp_ctt,  buf, len,  prh_ctt->sequence_num);
						(*len)=0;
						ms_debug("%u--%u,error sequence_num(sequence_num_need<sequence_num),rtptfifo_ptknum:%d",
							prtp_ctt->sequence_num_need, prh_ctt->sequence_num,prtp_ctt->rtptfifo_ptknum);
						return;
					}
				}
			}
		}
		prtp_ctt->sequence_num_pre=prh_ctt->sequence_num;
		prtp_ctt->sequence_num_need=prh_ctt->sequence_num+1;
		(*len)-=prh_ctt->header_total_len;
		ms_selfcp(buf, prh_ctt->header_total_len, (*len));
	}
}

ms_bool msprotocol_api_parserequest(char *inbuf,WEBREQUESTContext *prequest_ctt)
{
	memset(prequest_ctt,0,sizeof(WEBREQUESTContext));

	ms_bool flag_lineend_unusual=ms_false;
	if(ms_false==msstr_api_iscasestr(inbuf,"\r\n\r\n")){
		flag_lineend_unusual=ms_true;
	}
	if(ms_false==msstr_api_iscasestr(inbuf, "Content-Length")){
		ms_s32 num_ret=msstr_api_casestr_num(inbuf, "\r\n\r\n", ms_false);
		ms_s32 num_ret_1=msstr_api_casestr_num(inbuf, "\r\n\r\n\r\n", ms_false);
		ms_s32 num_ret_2=msstr_api_casestr_num(inbuf, "\r\n\r\n\r\n\r\n", ms_false);
		if(num_ret>1&&
			!(1==num_ret_1&&2==num_ret)&&
			!(1==num_ret_2&&3==num_ret)){
			flag_lineend_unusual=ms_true;
			#if 0
			ms_errret(ms_false, "Oh,has %d * \\r\\n\\r\\n,inbuf:\r\n%s",num_ret,inbuf);
			#else
			ms_waring("Oh,has %d * \\r\\n\\r\\n,inbuf:\r\n%s",num_ret,inbuf);
			#endif
		}
	}
	char *p =inbuf;	
	ms_more("%s",inbuf);
	msstr_api_getword(prequest_ctt->method, sizeof(prequest_ctt->method), (const char **)&p);	
	ms_more("1.%s ",prequest_ctt->method);
	msstr_api_getword(prequest_ctt->url, sizeof(prequest_ctt->url), (const char **)&p);
	ms_more("2.%s",prequest_ctt->url);
	msstr_api_getword(prequest_ctt->protocol, sizeof(prequest_ctt->protocol), (const char **)&p);
	ms_more("3.%s",prequest_ctt->protocol);
	char tbuf[5120]={0};

	prequest_ctt->falg_hascontent=ms_false;
	ms_bool flag_end=ms_false;
	if(msstr_api_iscasestr(prequest_ctt->protocol, "HTTP") !=0){

		ms_byte temp_url[5120];
		ms_strcpy(temp_url,prequest_ctt->url);
		ms_string str_array_item[16];
		ms_s32 num_param=msstr_api_split(temp_url, "?", str_array_item);
		ms_s32 item_index=0;
		if(num_param>1){
			ms_strcpy(prequest_ctt->extern_data.http_rd.webhost_info.url_param,str_array_item[1]);
		}

		prequest_ctt->ptl_index=msptc_http;
		HTTPREQUESTData *phttp_rd=&prequest_ctt->extern_data.http_rd;
		while(0!=*p){
			ms_memset(tbuf,0,sizeof(tbuf));
			if(ms_true==prequest_ctt->falg_hascontent){
				msstr_api_getline_withend(tbuf, sizeof(tbuf), (const char **)&p);
				//ms_debug("1-----------tbuf:%s",tbuf);
			}else{
				msstr_api_getword(tbuf, sizeof(tbuf), (const char **)&p);
				//ms_debug("2-----------tbuf:%s",tbuf);
			}
			if(ms_true==prequest_ctt->falg_hascontent){
				if(ms_false==flag_end){
					if(ms_strncmps_aeq(tbuf, "\r\n")
						||ms_strncmps_aeq(tbuf, "\r")){
						flag_end=ms_true;
					}
				}else{
					if(ms_buflen(tbuf)>0){
						ms_byte tbuftmp[5120];
						ms_strcats(tbuftmp,prequest_ctt->content,"%s",tbuf);
					}
				}
				//ms_debug("content(%d):\r\n%s",(ms_s32)ms_buflen(prequest_ctt->content),prequest_ctt->content);
			}else if(msstr_api_iscasestr(tbuf, "Host:") !=0){
				WEBHOSTInfo *pwebhost_info=&prequest_ctt->extern_data.http_rd.webhost_info;
				msstr_api_getword(tbuf, sizeof(tbuf), (const char **)&p);
				ms_sprintfs(phttp_rd->webhost_info.server_host,"%s",tbuf);
#if 0				
				int index_server_host=0;
				int index_server_ip=0;
				int index_server_port=0;
				char is_port=0;
				while(0!=phttp_rd->webhost_info.server_host[index_server_host]){
					if(':'==phttp_rd->webhost_info.server_host[index_server_host]){
						is_port=1;
						index_server_host++;
						continue;
					}
					if(1==is_port){
						phttp_rd->webhost_info.server_port[index_server_port++]=phttp_rd->webhost_info.server_host[index_server_host++];
					}else{
						phttp_rd->webhost_info.server_ip[index_server_ip++]=phttp_rd->webhost_info.server_host[index_server_host++];
					}
				}
#else
				ms_byte protocol_name[128]={0};
				ms_byte authorization[64]={0};
				ms_byte path[128]={0};
				ms_byte server_ip[128]={0};
				ms_byte url[1024]={0};
				ms_u32 port;
				ms_sprintfs(url, "http://%s", phttp_rd->webhost_info.server_host);
				msstr_api_urlsplit_autosize(
					protocol_name, 
					authorization, 
					server_ip, 
					&port, 
					path,
					&phttp_rd->webhost_info.flag_ipv6,
					url);
#endif
				ms_sprintfs(phttp_rd->webhost_info.server_port, "%d", port);
				ms_more("url:%s",url);
				ms_more("server_host:%s",phttp_rd->webhost_info.server_host);
				if(phttp_rd->webhost_info.flag_ipv6){
					ms_sprintfs(phttp_rd->webhost_info.server_ip, "[%s]",server_ip);
				}else{
					ms_strcpy(phttp_rd->webhost_info.server_ip, server_ip);
				}
				ms_more("server_ip:%s",phttp_rd->webhost_info.server_ip);
				ms_more("server_port:%s",phttp_rd->webhost_info.server_port);
			}else if(msstr_api_iscasestr(tbuf, "User-Agent:") !=0){
				msstr_api_getline(tbuf, sizeof(tbuf), (const char **)&p);
				ms_sprintfs(prequest_ctt->user_agent,"%s",tbuf);
				ms_verbose("User-Agent:%s",prequest_ctt->user_agent);
			}else	 if(msstr_api_iscasestr(tbuf, "Content-Type:") !=0){
				msstr_api_getline(tbuf, sizeof(tbuf), (const char **)&p);
				ms_sprintfs(prequest_ctt->content_type,"%s",tbuf);
				ms_verbose("Content-Type:%s",prequest_ctt->content_type);
			}else	 if(msstr_api_iscasestr(tbuf, "Content-Length:") !=0){
				msstr_api_getline(tbuf, sizeof(tbuf), (const char **)&p);
				prequest_ctt->content_len=ms_atoi(tbuf);
				ms_verbose("Content-Length=%d",prequest_ctt->content_len);
				prequest_ctt->falg_hascontent=ms_true;
				ms_memsetbuf(prequest_ctt->content);
			}else	 if(msstr_api_iscasestr(tbuf, "Connection:") !=0){
				msstr_api_getline(tbuf, sizeof(tbuf), (const char **)&p);
				ms_sprintfs(prequest_ctt->connection,"%s",tbuf);
				ms_verbose("Connection=%s",prequest_ctt->connection);
			}
		}
	}else  if(msstr_api_iscasestr(prequest_ctt->protocol, "RTSP") !=0){ 
		prequest_ctt->ptl_index=msptc_rtsp;
		RTSPREQUESTData *prtsp_rd=&prequest_ctt->extern_data.rtsp_rd;
		while(0!=*p){
			memset(tbuf,0,sizeof(tbuf));
			if(ms_true==prequest_ctt->falg_hascontent){
				msstr_api_getline_withend(tbuf, sizeof(tbuf), (const char **)&p);
				//ms_debug("1-----------tbuf:%s",tbuf);
			}else{
				msstr_api_getword(tbuf, sizeof(tbuf), (const char **)&p);
				//ms_debug("2-----------tbuf:%s",tbuf);
			}
			if(ms_true==prequest_ctt->falg_hascontent){
				if(ms_false==flag_end){
					if(ms_strncmps_aeq(tbuf, "\r\n")
						||ms_strncmps_aeq(tbuf, "\r")){
						flag_end=ms_true;
					}
				}else{
					if(ms_buflen(tbuf)>0){
						ms_byte tbuftmp[5120];
						ms_strcats(tbuftmp,prequest_ctt->content,"%s",tbuf);
					}
				}
				//ms_debug("content(%d):\r\n%s",(ms_s32)ms_buflen(prequest_ctt->content),prequest_ctt->content);
			}else if(msstr_api_iscasestr(tbuf, "CSeq") !=0){
				msstr_api_getword(tbuf, sizeof(tbuf), (const char **)&p);
				ms_sprintfs(prtsp_rd->CSeq,"%s",tbuf);
			}else if(msstr_api_iscasestr(tbuf, "Transport") !=0){
				msstr_api_getword(tbuf, sizeof(tbuf), (const char **)&p);
				ms_sprintfs(prtsp_rd->Transport,"%s",tbuf);
			}else if(msstr_api_iscasestr(tbuf, "Range") !=0){
				msstr_api_getword(tbuf, sizeof(tbuf), (const char **)&p);
				ms_sprintfs(prtsp_rd->Range,"%s",tbuf);
			}else if(msstr_api_iscasestr(tbuf, "Session") !=0){
				msstr_api_getword(tbuf, sizeof(tbuf), (const char **)&p);
				ms_sprintfs(prtsp_rd->Session,"%s",tbuf);
			}else if(msstr_api_iscasestr(tbuf, "pscAccept") !=0){
				msstr_api_getword(tbuf, sizeof(tbuf), (const char **)&p);
				ms_sprintfs(prtsp_rd->pscAccept,"%s",tbuf);
			}else	 if(msstr_api_iscasestr(tbuf, "User-Agent:") !=0){
				msstr_api_getline(tbuf, sizeof(tbuf), (const char **)&p);
				ms_sprintfs(prequest_ctt->user_agent,"%s",tbuf);
				ms_verbose("User-Agent:%s",prequest_ctt->user_agent);
			}else	 if(msstr_api_iscasestr(tbuf, "Content-Type:") !=0){
				msstr_api_getline(tbuf, sizeof(tbuf), (const char **)&p);
				ms_sprintfs(prequest_ctt->content_type,"%s",tbuf);
				ms_verbose("Content-Type:%s",prequest_ctt->content_type);
			}else	 if(msstr_api_iscasestr(tbuf, "Content-Length:") !=0){
				msstr_api_getline(tbuf, sizeof(tbuf), (const char **)&p);
				ms_sprintfs(prequest_ctt->user_agent,"%s",tbuf);
				prequest_ctt->content_len=ms_atoi(tbuf);
				ms_verbose("Content-Length=%d",prequest_ctt->content_len);
				prequest_ctt->falg_hascontent=ms_true;
				ms_memsetbuf(prequest_ctt->content);
			}
		}
		ms_more("CSeq:%s",prtsp_rd->CSeq);
		ms_more("Transport:%s",prtsp_rd->Transport);
		ms_more("Range:%s",prtsp_rd->Range);
		ms_more("Session:%s",prtsp_rd->Session);
		ms_more("pscAccept:%s",prtsp_rd->pscAccept);	
		ms_more("user_agent:%s",prequest_ctt->user_agent);	
	}

	if((ms_true==prequest_ctt->falg_hascontent)
		&&(prequest_ctt->content_len!=ms_buflen(prequest_ctt->content))){
		if(prequest_ctt->content_len>ms_buflen(prequest_ctt->content)){
			ms_waring("content_len(%d)  != ms_buflen(content)(%d)", prequest_ctt->content_len,(ms_s32)ms_buflen(prequest_ctt->content));
		}else{
			ms_debug("content_len(%d)  != ms_buflen(content)(%d)", prequest_ctt->content_len,(ms_s32)ms_buflen(prequest_ctt->content));
		}
		ms_bufascii("content", prequest_ctt->content,ms_buflen(prequest_ctt->content));
		ms_buf("content", prequest_ctt->content,ms_buflen(prequest_ctt->content));
	}

	ms_bool  retend=ms_true;
	if(ms_true==flag_lineend_unusual
		&&(ms_false==msstr_api_iscasestr(prequest_ctt->user_agent, "EBS"))){
		retend=ms_false;
	}
	return retend;
}

ms_s08 msprotocol_api_init(void)
{
	extern ms_s08 tssl_init(ms_string ca_file,ms_string cert_file,ms_string key_file,ms_bool flag_verify);
	//srt_startup();
	ms_string cert_file	="/etc/mscore/cert/https.crt";
	ms_string key_file 	="/etc/mscore/cert/https.key";
	if(tssl_init(ms_null,cert_file,key_file,ms_false)<0){
		ms_errret(-1, "tssl_init  failed");
	}
}
void msprotocol_api_deinit(void)
{
	extern ms_void tssl_deinit(ms_void);
	//srt_cleanup();
	tssl_deinit();
}
void register_protocol(void)
{
#define REGISTER_PROTOCOL(x) { \
    extern URLProtocol ffurl_##x##_protocol; \
    extern int ffurl_register_protocols(URLProtocol *, int );\
    ffurl_register_protocols(&ffurl_##x##_protocol, sizeof(URLProtocol)); \
    ms_verbose("*  %s" ,ffurl_##x##_protocol.name); }
	ms_verbose("===PROTOCOL *  Table===");	
	REGISTER_PROTOCOL(raw);	
	REGISTER_PROTOCOL(udp);	
	REGISTER_PROTOCOL(udplite);
	REGISTER_PROTOCOL(tcp);	
#if defined CONFIG_MSPROTOCOL_TSSL 
	REGISTER_PROTOCOL(tssl);	
#endif
	//REGISTER_PROTOCOL(srt);	
	REGISTER_PROTOCOL(rtp);
	REGISTER_PROTOCOL(rtsp);	
	REGISTER_PROTOCOL(http);
	REGISTER_PROTOCOL(hls);
	REGISTER_PROTOCOL(file);
	REGISTER_PROTOCOL(pipe);
	REGISTER_PROTOCOL(none);		//use to do test out
#ifdef CONFIG_MSPROTOCOL_LIBRTMP
	REGISTER_PROTOCOL (rtmp);
	REGISTER_PROTOCOL (rtmpt);
	REGISTER_PROTOCOL (rtmpe);
	REGISTER_PROTOCOL (rtmpte);
	REGISTER_PROTOCOL (rtmps);
#endif
#ifdef CONFIG_MSPROTOCOL_MSAV
	REGISTER_PROTOCOL(msav);
#endif
	ms_verbose("========================");	
}
ms_void msprotocol_api_infofunc(ms_string ms_out pbuf)
{
#if defined OS_LINUX_SOC  
	#if defined OS_PLATFORM_ARM64  
		strcat(pbuf, "linux_aarch64");
	#elif defined OS_PLATFORM_ARMV7L
		strcat(pbuf, "linux_armv7l");
	#else
		strcat(pbuf, "linux_soc");
	#endif
#else
	#if defined OS_PLATFORM_ARM64  
		strcat(pbuf, "unlinux_aarch64");
	#elif defined OS_PLATFORM_ARMV7L
		strcat(pbuf, "unlinux_armv7l");
	#else
		strcat(pbuf, "unlinux_soc");
	#endif
#endif
#if SOC_PLATFORM_RK3399
	strcat(pbuf, "|rk3399");
#endif
	strcat(pbuf, "|raw");
	strcat(pbuf, "|udp");
	strcat(pbuf, "|udplite");
	strcat(pbuf, "|tcp");
#if defined CONFIG_MSPROTOCOL_TSSL 
	strcat(pbuf, "|tssl");
#else
	strcat(pbuf, "|no-tssl");
#endif
	strcat(pbuf, "|rtp");
	strcat(pbuf, "|rtsp");
	strcat(pbuf, "|http");
	strcat(pbuf, "|hls");
	strcat(pbuf, "|file");
	strcat(pbuf, "|pipe");
	strcat(pbuf, "|none");
#ifdef CONFIG_MSPROTOCOL_LIBRTMP
	strcat(pbuf, "|rtmp");
	strcat(pbuf, "|rtmpt");
	strcat(pbuf, "|rtmpe");
	strcat(pbuf, "|rtmpte");
	strcat(pbuf, "|rtmps");
#else
	strcat(pbuf, "|no-librtmp");
#endif
#ifdef CONFIG_MSPROTOCOL_MSAV
	strcat(pbuf, "|msav");
#else
	strcat(pbuf, "|no-msav");
#endif
}
ms_s32 msprotocol_api_io(URLContext *pcilent_ctt, ms_pu08 buf, ms_s32 len,ms_s32 (*url_io)(URLContext *, ms_pu08 , ms_s32 ))
{
	ms_s32 io_len=0;
	ms_s32 total_len=len;
	while(total_len>0){
		io_len=url_io(pcilent_ctt,buf,total_len);
		if(io_len>0){
			total_len-=io_len;
		}else{
			break;
		}
	}
	return	(len- total_len);
}

ms_string msprotocol_api_version(ms_void)
{
	return "01.02.04";
}
#undef MSPROTOCOL_C
